package com.ahnu.tongue.aspect;

import com.ahnu.tongue.annotation.OperationLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class OperationLogAspect {

    @Around("@annotation(com.ahnu.tongue.annotation.OperationLog)")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = null;
        try {
            result = point.proceed();
            recordOperationLog(point, null, System.currentTimeMillis() - startTime);
            return result;
        } catch (Exception e) {
            recordOperationLog(point, e, System.currentTimeMillis() - startTime);
            throw e;
        }
    }

    private void recordOperationLog(ProceedingJoinPoint point, Exception e, long time) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        OperationLog operationLog = method.getAnnotation(OperationLog.class);

        // 获取请求信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Long userId = (Long) request.getAttribute("userId");

        // 构建日志信息
        String logInfo = String.format(
            "操作日志 - 用户ID: %d, 操作类型: %s, 描述: %s, URL: %s, 方法: %s, 参数: %s, 执行时间: %dms, 时间: %s%s",
            userId,
            operationLog.operationType(),
            operationLog.description(),
            request.getRequestURI(),
            method.getName(),
            Arrays.toString(point.getArgs()),
            time,
            LocalDateTime.now(),
            e != null ? ", 异常: " + e.getMessage() : ""
        );

        // 记录日志
        if (e != null) {
            log.error(logInfo, e);
        } else {
            log.info(logInfo);
        }

        // TODO: 这里可以将日志保存到数据库中
    }
} 